#!/bin/bash

set -e

# 默认缓冲区大小（可覆盖）
DEFAULT_BUFFER_SIZE=${1:-4096}


# 安装依赖
install_dependencies() {
    if ! command -v ethtool &> /dev/null; then
        echo "安装ethtool中..."
        if command -v apt-get &> /dev/null; then
            apt-get -qq update > /dev/null
            apt-get -qq install -y ethtool > /dev/null
        elif command -v yum &> /dev/null; then
            yum -q install -y ethtool > /dev/null
        elif command -v dnf &> /dev/null; then
            dnf -q install -y ethtool > /dev/null
        else
            echo "错误：不支持的操作系统"
            exit 1
        fi
    fi
}

# 检测物理网卡
detect_physical_interfaces() {
    # 排除虚拟网卡和环回接口
    local interfaces=()
    for iface in /sys/class/net/*; do
        local iface_name=$(basename "$iface")
        # 排除虚拟接口和环回
        if [[ "$iface_name" != "lo" && 
              ! "$iface_name" =~ ^virbr ]] && 
           [[ ! -d "$iface/device" || -L "$iface" ]]; then
            # 检查是否支持环形缓冲区设置
            if ethtool -g "$iface_name" &> /dev/null; then
                interfaces+=("$iface_name")
            fi
        fi
    done
    echo "${interfaces[@]}"
}

# 获取网卡最大环形缓冲区值
get_max_ring() {
    local iface=$1
    local type=$2
    ethtool -g "$iface" | awk -v t="$type" '
        /^Pre-set maximums:/ { active=1 }
        active && $1 == t ":" { print $2; exit }
    '
}

# 优化单个网卡
optimize_interface() {
    local iface=$1
    local desired=$2
    
    echo -e "\n正在优化网卡: \033[1;34m$iface\033[0m"
    
    # 获取最大允许值
    local max_rx=$(get_max_ring "$iface" "RX")
    local max_tx=$(get_max_ring "$iface" "TX")
    
    if [ -z "$max_rx" ] || [ -z "$max_tx" ]; then
        echo "警告: 无法获取最大环形缓冲区值，跳过"
        return
    fi
    
    # 计算实际设置值
    local rx=$(( desired > max_rx ? max_rx : desired ))
    local tx=$(( desired > max_tx ? max_tx : desired ))
    
    # 检查当前值
    local current_rx=$(ethtool -g "$iface" | awk '/^Current hardware settings:/ {active=1} active && /RX:/ {print $2; exit}')
    local current_tx=$(ethtool -g "$iface" | awk '/^Current hardware settings:/ {active=1} active && /TX:/ {print $2; exit}')
    
    # 跳过已优化的网卡
    if [ "$current_rx" -eq "$rx" ] && [ "$current_tx" -eq "$tx" ]; then
        echo "已是最优值 (RX=$rx, TX=$tx)"
        return
    fi
    
    # 执行优化
    if ethtool -G "$iface" rx "$rx" tx "$tx" > /dev/null; then
        echo " 优化成功: RX=$rx (最大:$max_rx), TX=$tx (最大:$max_tx)"
        echo " 原值: RX=$current_rx, TX=$current_tx"
    else
        echo " 错误: 设置失败，网卡可能不支持"
    fi
}

# 显示网卡统计信息
show_interface_stats() {
    local iface=$1
    echo -e "\n\033[1;36m$iface 统计信息:\033[0m"
    
    # 显示丢包信息
    ethtool -S "$iface" | grep -iE 'drop|error|discard|fifo' | grep -v ' 0$' | sort | \
    awk '{printf "  %-35s %12s\n", $1, $2}' | \
    sed -E 's/(.*[0-9])([^0-9]*)$/\1\n  \2/'
    
    # 显示环形缓冲区当前值
    echo -e "\n  \033[1;33m当前环形缓冲区:\033[0m"
    ethtool -g "$iface" | grep -A 10 'Current hardware' | grep -E 'RX:|TX:' | \
    while read -r line; do
        echo "  $line"
    done
}

# 主函数
main() {
    install_dependencies
    
    # 检测所有物理网卡
    local interfaces=($(detect_physical_interfaces))
    
    if [ ${#interfaces[@]} -eq 0 ]; then
        echo "未找到支持的物理网卡"
        exit 1
    fi
    
    echo "检测到物理网卡: ${interfaces[*]}"
    echo "设置缓冲区大小: $DEFAULT_BUFFER_SIZE"
    
    # 优化所有检测到的网卡
    for iface in "${interfaces[@]}"; do
        optimize_interface "$iface" "$DEFAULT_BUFFER_SIZE"
    done
    
    # 显示优化后统计信息
    echo -e "\n\033[1;35m优化完成！当前网络统计:\033[0m"
    for iface in "${interfaces[@]}"; do
        show_interface_stats "$iface"
    done
    
    # 给出建议
    echo -e "\n\033[1;32m后续建议:\033[0m"
    echo "1. 使用 'ip -s link show dev <网卡>' 监控实时流量"
    echo "2. 使用 'ethtool -S <网卡> | grep -i drop' 监控丢包情况"
    echo "3. 如果仍有丢包，可尝试增大缓冲区值重新运行脚本"
    echo "4. 考虑调整内核参数: net.core.netdev_max_backlog"
    echo "   临时设置: sudo sysctl -w net.core.netdev_max_backlog=5000"
}

# 执行主函数
main